package nz.ac.massey.groupproject.ecs2;

import java.util.ArrayList;
import java.util.List;


public class GameState {
	public final static int MINX = 0;
	public final static int MAXX = 797;
	public final static int MINY = 0;
	public final static int MAXY = 597;
	public final static int XSPAN = MAXX - MINX + 1;
	public final static int YSPAN = MAXY - MINY + 1;


	public final ArrayList<UserCommand>    pendingCmds     = new ArrayList<UserCommand>();
	public int                             playerMovDirDX  = 0;
	public int                             playerMovDirDY  = 0;
	public final ArrayList<ECSEntity>      walls           = new ArrayList<ECSEntity>();    // FIXME This is ugly. we should clean this up later.


	public void registerSystems(List<ECSSystem> pipeline) {
		pipeline.add(new ComputePlayerMovementDirection());
		pipeline.add(new LinearBouncebackMotionSystem());
		pipeline.add(new            OrbitMotionSystem());
		pipeline.add(new   UserControlledMotionSystem());
		pipeline.add(new                SpawnerSystem());
	}

	public void spawnTestEntities(ECSWorld world) { // TODO perhaps convert this to a system?
			addWall(world, 400, 200, new Polygon(0, 0, 50, 0, 0, 50));

			world.add(EntFactory.player(400, 300));
			world.add(EntFactory.stationarySpawner(50, 100, 7));
			world.add(EntFactory.stationarySpawner(50, 500, 4));
			world.add(new ECSEntity(new Position(400, 300), new LinearBouncebackMotion(2, 0), Appearance.TINY_DOT, new SpawnerComponent(2)));
			world.add(EntFactory.orbitingThingie(50, 500, 20, 6, 90));
			world.add(EntFactory.orbitingThingie(50, 500, 20, 6, 270));
			world.add(new ECSEntity(new Position(400, 270), new UserControlledMotion(), Appearance.SMALL_DOT, new SpawnerComponent(2)));
	}


	public void addWall(ECSWorld world, int x, int y, Polygon poly) {
		var wall = new ECSEntity(new WallTag(), new Position(x, y), Appearance.PLAYER, new PolygonComponent(poly));     // Appearance serves as a visual reference point
		world.add(wall);
		walls.add(wall);
	}

	public class ComputePlayerMovementDirection implements ECSSystem {
		public void globalTick() {
			int dx = 0, dy = 0;

			for (var cmd : pendingCmds) {
				if      (UserCommand.LEFT    == cmd) dx--;
				else if (UserCommand.RIGHT   == cmd) dx++;
				else if (UserCommand.FORWARD == cmd) dy++;
				else if (UserCommand.BACK    == cmd) dy--;
				else throw new RuntimeException("Internal error: unhandled command");
			}
			pendingCmds.clear();

			playerMovDirDX = dx;
			playerMovDirDY = dy;
		}
	}
}

enum UserCommand {
	QUIT,
	LEFT, RIGHT, FORWARD, BACK
}
